﻿using NUnit.Framework;
using RenewalProjects.Libraries.Common.Testing.Interfaces;
using RenewalProjects.Libraries.Wcf.EasyProxy.ChannelAllocators.Factories;
using RenewalProjects.Libraries.Wcf.EasyProxy.ChannelHolders;
using RenewalProjects.Libraries.Wcf.EasyProxy.Tests.FixtureHelpers;
using RenewalProjects.Libraries.Wcf.EasyProxy.Tests.TestData;
using Rhino.Mocks;

namespace RenewalProjects.Libraries.Wcf.EasyProxy.Tests.Fixtures
{
	[TestFixture]
	public class PooledChannelAllocatorFixture : IUsesRhinoMocks
	{
	    #region Properties
	    
	    public MockRepository Mock { get; set; }
	    
	    #endregion
	    
	    #region Test methods
	    
	    [SetUp]
	    public void Reset_factory_methods()
	    {
	        PooledChannelResourceProviderFactory<ITest>.ResetFactoryMethods();
	    }
	    
		[Test]
		public void PooledChannelAllocator_refresh_channels_for_ready_pool()
		{
		    var helper = new PooledChannelAllocatorFixtureHelper<ITest>(Mock, new TestChannel())
			    .MakeReadyChannelsAvailable(true)
			    .MakeStandbyChannelsAvailable(false);
			
			Mock.ReplayAll();
			
			helper.RefreshChannelPools();
		}
		
		[Test]
		public void PooledChannelAllocator_refresh_channels_for_standby_pool()
		{
		    var helper = new PooledChannelAllocatorFixtureHelper<ITest>(Mock, new TestChannel())
			    .MakeReadyChannelsAvailable(false)
			    .MakeStandbyChannelsAvailable(true);
			
			Mock.ReplayAll();
			
			helper.RefreshChannelPools();
		}
		
		[Test]
		public void PooledChannelAllocator_get_available_ready_channel()
		{
		    var helper = new PooledChannelAllocatorFixtureHelper<ITest>(Mock, new TestChannel())
		        .MakeReadyChannelsAvailable(true)
		        .MakeStandbyChannelsAvailable(false)
		        .MakeReadyResourceAvailable(true);
		    
		    Mock.ReplayAll();
		    
		    var channelHolder = helper.GetAvailableChannel();
		    Assert.IsNotNull(channelHolder);
		    Assert.IsInstanceOf<ReadyChannelHolder<ITest>>(channelHolder);
		}
		
		[Test]
		public void PooledChannelAllocator_ready_channel_unavailable_use_transient()
		{
		    var helper = new PooledChannelAllocatorFixtureHelper<ITest>(Mock, new TestChannel())
		        .MakeReadyChannelsAvailable(true)
		        .MakeStandbyChannelsAvailable(false)
		        .MakeReadyResourceAvailable(false)
		        .ExpectChannelCreation(true);
		    
		    Mock.ReplayAll();
		    
		    var channelHolder = helper.GetAvailableChannel();
		    Assert.IsNotNull(channelHolder);
		    Assert.IsInstanceOf<TransientChannelHolder<ITest>>(channelHolder);
		}
		
		[Test]
		public void PooledChannelAllocator_get_available_standby_channel()
		{
		    var helper = new PooledChannelAllocatorFixtureHelper<ITest>(Mock, new TestChannel())
		        .MakeReadyChannelsAvailable(false)
		        .MakeStandbyChannelsAvailable(true)
		        .MakeStandbyResourceAvailable(true);
		    
		    Mock.ReplayAll();
		    
		    var channelHolder = helper.GetAvailableChannel();
		    Assert.IsNotNull(channelHolder);
		    Assert.IsInstanceOf<StandbyChannelHolder<ITest>>(channelHolder);
		}
		
		[Test]
		public void PooledChannelAllocator_standby_channel_unavailable_use_transient()
		{
		    var helper = new PooledChannelAllocatorFixtureHelper<ITest>(Mock, new TestChannel())
		        .MakeReadyChannelsAvailable(false)
		        .MakeStandbyChannelsAvailable(true)
		        .MakeStandbyResourceAvailable(false)
		        .ExpectChannelCreation(true);
		    
		    Mock.ReplayAll();
		    
		    var channelHolder = helper.GetAvailableChannel();
		    Assert.IsNotNull(channelHolder);
		    Assert.IsInstanceOf<TransientChannelHolder<ITest>>(channelHolder);
		}
		
		#endregion
	}
}